package com.baoji.auth.utils;

import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.DefaultJws;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Auther: ghm
 * @Date: 2021/09/24/14:47
 * @Description:
 */
@Slf4j
public class JwtTokenUtil {
    // Token 请求头
    public static final String TOKEN_HEADER = "Authorization";
    // Token 前缀
    public static final String TOKEN_PREFIX = "Bearer ";
    // Refresh-Token
    public static final String REFRESH_TOKEN = "Refresh-Token";
    // 签名主题
    public static final String SUBJECT = "piconjo";
    // token 过期时间
    public static final long TOKEN_EXPIRITION = 1000 * 30;
    // refreshToken 过期时间 1000 * 24 * 60 * 60 * 7
    public static final long REFRESH_TOKEN_EXPIRITION = 1000 * 60 * 2;
    // 应用密钥
    public static final String APPSECRET_KEY = "piconjo_secret";
    // 角色权限声明
    private static final String ROLE_CLAIMS = "role";

    /**
     * 生成Token 和 refresh token
     */
    public static String createToken(String username, String role, long expirition) {
        Map<String, Object> map = new HashMap<>();
        map.put(ROLE_CLAIMS, role);

        String token = Jwts
                .builder()
                .setSubject(username)
                .setClaims(map)
                .claim("username", username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + expirition))
                .signWith(SignatureAlgorithm.HS256, APPSECRET_KEY).compact();
        return token;
    }

    /**
     * 校验 Token
     * 放在上面检测
     */
    public static Jws<Claims> checkJWT(String token) {
        try {
            final Jws<Claims> claims = Jwts.parser().setSigningKey(APPSECRET_KEY).parseClaimsJws(token);
            return claims;
        } catch (ExpiredJwtException e) {
            return new DefaultJws<>(null, e.getClaims(), "");
        } catch (UnsupportedJwtException | MalformedJwtException | SignatureException | IllegalArgumentException | IncorrectClaimException e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    // 判断 jwt 是否过期; 过期 true:过期 false:没过期
    public static boolean isExpiration(Jws<Claims> jws) {
      return jws.getBody().getExpiration().before(new Date());
    }

    // 获取用户名
    public static String getUsername(Jws<Claims> jws) {
        return jws.getBody().get("username").toString();
    }

    // 获取用户权限
    public static String getUserRole(Jws<Claims> jws) {
        return jws.getBody().get("role").toString();
    }
}
